-- slime_weaken_damage
-- create by shuzy
-- 对目标施加伤害并附加状态（专属用）

return {
    apply = function(source, target, skillId, round, para, extra)
        -- 专属技能等级
        local level;
        extra = extra or {};
        if extra["level"] then
            level = tonumber(extra["level"]);
        else
            local prop = PropM.combine(source, "gain_slime_skill", para[1]);
            level = PropM.apply(prop, 0);
        end

        local effectRound = -1;
        local lastRound = extra.lastRound;
        if type(lastRound) == "number" then
            effectRound = round + lastRound + 1;
        elseif para[6] > 0 then
            -- 不包括本回合
            effectRound = round + para[6] + 1;
        end

        -- 威力
        local base = para[2];
        local force = para[3];

        -- 攻击方的攻击
        local attack = source:getAttack();

        -- 伤害
        local damage = math.modf(attack * (base + force * level) / 1000);

        -- 斯巴达专属加成
        local prop = PropM.combine(source, "battle_cry", 1);
        if prop[3] > 0 then
            -- 触发特技发动事件
            EventMgr.fire(event.SPECIAL_SKILL_TRIGGER, { propId = prop[1] });
        end
        damage = PropM.apply(prop, damage);

        -- 连携附带暴击效果
        prop = PropM.combine(source, "even_carrying", "crit");
        if FormulaM.invoke("CAN_EVEN_CARRYING", skillId) and prop[3] > 0 then
            damage = damage + PropM.trigger(source, prop[1], prop[2], damage);
        end

        local condition = {
            ["value"] = para[5],
            ["end_round"] = effectRound,
        };

        -- 增加命中动作
        SkillM.getSequence(target):hit(source, target, skillId);

        -- 作用
        CombatM.receiveDamage(source, target, damage, skillId, extra);
        if not target:isDead() and not SkillM.immunitySkill(source, target, skillId) then
            CombatStatusM.applyStatus(target, para[4], condition);
        end

        -- 如果是玩家，抛出攻击结果事件
        if source.type == OBJECT_TYPE_USER then
            EventMgr.fire(event.HERO_ATTACK_RESULT, { ["damage"] = damage, ["extra"] = extra});
        end

        -- 连携附带穿击炮效果，伤害范围加（距离N以内敌人一起打击）
        prop = PropM.combine(source, "even_carrying", "strike");
        if FormulaM.invoke("CAN_EVEN_CARRYING", skillId) and prop[3] > 0 then
            -- 遍历所有的怪
            local ret = {};

            local pos = target.dbase:query("pos");
            if not pos then
                pos = target:getOwner();
            end
            local coor = DungeonM.convertToCoor(pos);

            -- 取出场上已翻开且未死亡的怪物
            for p = 1, DUNGEON_WIDTH * DUNGEON_HEIGHT do
                local grid = DungeonM.getGridByPos(p);
                local c = DungeonM.convertToCoor(p);

                -- 有效范围内
                local near = math.abs(c.x - coor.x) + math.abs(c.y - coor.y) <= prop[3];

                -- 翻开且存活的怪物
                if  near and grid:isOpened() and
                    grid:isMonster() and
                    grid.monster ~= target and
                    not grid.monster:isDead() then
                    table.insert(ret, grid.monster);
                end
            end

            -- 作用
            for _, monster in pairs(ret) do
                -- 增加命中动作
                SkillM.getSequence(target):hit(source, monster, skillId);

                CombatM.receiveDamage(source, monster, damage, skillId, extra);
                if not monster:isDead() and not SkillM.immunitySkill(source, monster, skillId) then
                    CombatStatusM.applyStatus(monster, para[4], condition);
                end
            end
        end

        -- 作用目标
        return { target, };
    end,

    parse = function(desc)
        local arr = string.explode(desc, ",");
        return { tonumber(arr[1]), tonumber(arr[2]), tonumber(arr[3]), arr[4], tonumber(arr[5]), tonumber(arr[6]) };
    end,

    -- 解析技能描述
    parseDesc = function(source, skillId, desc, para)
        -- 专属技能等级
        local prop = PropM.combine(source, "gain_slime_skill", para[1]);
        local level = PropM.apply(prop, 0);

        -- 威力
        local base = para[2];
        local force = para[3];

        -- 攻击方的攻击
        local attack = source:getAttack();

        -- 伤害
        local damage = math.modf(attack * (base + force * level) / 1000);

        -- 斯巴达专属加成
        prop = PropM.combine(source, "battle_cry", 1);
        damage = PropM.apply(prop, damage);

        desc = string.gsub(desc, "{damage}", damage);

        local num = math.abs(para[5] / 10);
        desc = string.gsub(desc, "{num}", num);
        desc = string.gsub(desc, "{round}", para[6]);

        return desc;
    end,
};